﻿using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TSharp.Core;
using TSharp.Core.Osgi;
using TSharp.Core.Pattern;
using TSharp.Core.TestUtil;

//[assembly: RegLazyLoading(typeof(IServiceSituation), typeof(A))]

namespace Wicresot.CoreTests
{
    /// <summary>
    ///这是 SingletonBaseTest 的测试类，旨在
    ///包含所有 SingletonBaseTest 单元测试
    ///</summary>
    [TestClass]
    public class SingletonBaseTest
    {
        /// <summary>
        ///获取或设置测试上下文，上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext { get; set; }

        #region 附加测试特性

        // 
        //编写测试时，还可使用以下特性:
        //
        //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
            TestHelper.SetupTest(typeof (SingletonBaseTest));
        }

        //
        //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //使用 TestInitialize 在运行每个测试前先运行代码
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //使用 TestCleanup 在运行完每个测试后运行代码
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        [TestMethod]
        public void SingletonFactoryTest()
        {
            IServiceSituation actuala = null;
            IServiceSituation actualb = null;

            new Thread(x =>
                           {
                               actuala =
                                   SingletonHelper<IServiceSituation>.GetOrAdd(() =>
                                                                                   LazyLoading.New
                                                                                       <IServiceSituation>());

                               Console.WriteLine("a");
                           }).Start();

            new Thread(x =>
                           {
                               actualb =
                                   SingletonHelper<IServiceSituation>.GetOrAdd(
                                       () => LazyLoading.New<IServiceSituation>());

                               Console.WriteLine("b");
                           }).Start();

            Thread.Sleep(30);
            Console.WriteLine("a b ok");
            Console.WriteLine("a ?= b :" + ReferenceEquals(actuala, actualb));
            Assert.AreSame(actuala, actualb);
            IServiceSituation actualc = null;
            new Thread(x =>
                           {
                               actualc = new TestServiceSituation();
                               Console.WriteLine("b");
                           }).Start();

            Thread.Sleep(30);
            Console.WriteLine("c ok");
            Console.WriteLine("a ?= c :" + ReferenceEquals(actuala, actualc));

            Assert.AreNotSame(actuala, actualc);
        }


        [TestMethod]
        public void ThreadSingletonFactoryTest()
        {
            IServiceSituation actuala = null;
            IServiceSituation actualb = null;
            IServiceSituation actualc = null;
            var a = new Thread(x =>
                                   {
                                       actuala =
                                           TSharp.Core.Pattern.ThreadSingletonHelper<IServiceSituation>.GetOrAdd(() =>
                                                                                                 LazyLoading.
                                                                                                     New
                                                                                                     <IServiceSituation>
                                                                                                     ());

                                       Console.WriteLine("finish a");
                                   });
            a.Start();

            new Thread(x =>
                           {
                               actualb =
                                   TSharp.Core.Pattern.ThreadSingletonHelper<IServiceSituation>.GetOrAdd(
                                       () => LazyLoading.New<IServiceSituation>());
                               actualc =
                                   ThreadSingletonHelper<IServiceSituation>.GetOrAdd(
                                       () => LazyLoading.New<IServiceSituation>());

                               Console.WriteLine("finish b & c");
                           }).Start();

            Thread.Sleep(30);
            Console.WriteLine("a ?= b :" + ReferenceEquals(actuala, actualb));
            Assert.AreNotSame(actuala, actualb);


            Thread.Sleep(30);
            Console.WriteLine("b ?= c :" + ReferenceEquals(actualb, actualc));

            Assert.AreSame(actualb, actualc);
        }
    }
}